package com.example.distinguish_server.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.arcsoft.face.FaceFeature;
import com.arcsoft.face.FaceInfo;
import com.arcsoft.face.FaceSimilar;
import com.arcsoft.face.toolkit.ImageInfo;
import com.example.distinguish_server.Utils.Html.ResponseUtil;
import com.example.distinguish_server.Utils.ThreadCache.CacheSingleton;
import com.example.distinguish_server.entity.PhotoGallery;
import com.example.distinguish_server.entity.PlateNumber;
import com.example.distinguish_server.entity.Vo.AddFacesVo;
import com.example.distinguish_server.entity.Vo.FaceVo;
import com.example.distinguish_server.entity.Vo.PlateDeteVo;
import com.example.distinguish_server.entity.prop.JsonRootBean;
import com.example.distinguish_server.entity.prop.TokenResponse;
import com.example.distinguish_server.entity.prop.Vertexes_location;
import com.example.distinguish_server.entity.prop.Words_result;
import com.example.distinguish_server.pattern.Singleton.FaceEngineSing;
import com.example.distinguish_server.result.RLIST;
import com.example.distinguish_server.service.PhotoGalleryService;
import com.example.distinguish_server.service.PlateNumberService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.Base64;
import java.util.List;

import static com.arcsoft.face.toolkit.ImageFactory.getRGBData;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author xg
 * @since 2023-09-19
 */
@RestController
@RequestMapping("/photo-gallery")
public class PhotoGalleryController {
    @Autowired
    private PhotoGalleryService photoGalleryService;

    @Autowired
    private PlateNumberService plateNumberService;

    /**
     * 添加人脸特征数据
     */
    @ApiOperation(value = "添加人脸特征数据")
    @PostMapping("addFaces")
    public RLIST addFaces (@RequestParam("file") MultipartFile multipartFile, AddFacesVo addFacesVo){
        System.out.println(addFacesVo.toString() +" addFacesVo");

        String originalFilename = multipartFile.getOriginalFilename();

        String format = originalFilename.substring(originalFilename.length() - 4);
        if(!(format.equalsIgnoreCase(".jpg") || format.equalsIgnoreCase("jpeg"))){
                return RLIST.error().message("格式异常 需要jpg或jpeg");
        }
        String filePath = "D:\\fileFaces\\";
        File file = new File(filePath+originalFilename);
        if(!file.getParentFile().exists()){   //这里就判断了文件夹是否存在
            file.getParentFile().mkdirs();	//如果不存在就创建文件夹
        }
        try {
            multipartFile.transferTo(file);
        } catch (IOException e) {
            e.printStackTrace();
        }
        PhotoGallery photogallery = new PhotoGallery();
        FaceEngineSing instance = FaceEngineSing.getInstance();
        ImageInfo imageInfo2 = getRGBData(file);
        List<FaceInfo> detectFaces = instance.getDetectFaces(imageInfo2);
        if(detectFaces == null || detectFaces.size() == 0){
            return RLIST.error().message("图片不符合");
        }
        FaceInfo faceInfo = detectFaces.get(0);
        FaceFeature faceFeature = instance.getExtractFaceFeature(imageInfo2, detectFaces);
        byte[] featureData = faceFeature.getFeatureData();
        String featureDataStr = Base64.getEncoder().encodeToString(featureData);
        photogallery.setEigenvalue(featureDataStr);
        photogallery.setName(addFacesVo.getName());
        photogallery.setPleft(faceInfo.getRect().getLeft());
        photogallery.setPtop(faceInfo.getRect().getTop());
        photogallery.setPright(faceInfo.getRect().getRight());
        photogallery.setPbottom(faceInfo.getRect().getBottom());
        photogallery.setOrient(faceInfo.getOrient());
        System.out.println(photogallery.toString() +" toString");
        boolean compare = photoGalleryService.compare(photogallery);
        if(compare){
            return RLIST.error().message("人脸数据存在");
        }
        photoGalleryService.add(photogallery);
        return RLIST.ok();

    }

    /**
     * 人脸特征数据
     */
    @ApiOperation(value = "检测人脸特征")
    @PostMapping("/facialFeature")
    public RLIST facialFeature (@RequestParam("file") MultipartFile multipartFile,int docId){
        String originalFilename = multipartFile.getOriginalFilename();

        String format = originalFilename.substring(originalFilename.length() - 4);
        if(!(format.equalsIgnoreCase(".jpg") || format.equalsIgnoreCase("jpeg"))){
            return RLIST.error().message("格式异常 需要jpg或jpeg");
        }
        String filePath = "D:\\facialFeature\\";
        File file = new File(filePath+originalFilename);
        if(!file.getParentFile().exists()){   //这里就判断了文件夹是否存在
            file.getParentFile().mkdirs();	//如果不存在就创建文件夹
        }
        try {
            multipartFile.transferTo(file);
        } catch (IOException e) {
            e.printStackTrace();
        }
        float scoreMax = 0.800F;
        FaceVo faceVo = new FaceVo();
        FaceEngineSing instance = FaceEngineSing.getInstance();
        ImageInfo imageInfo2 = getRGBData(file);
        List<FaceInfo> detectFaces = instance.getDetectFaces(imageInfo2);
        FaceInfo faceInfo = detectFaces.get(0);
        if(detectFaces == null || detectFaces.size() == 0){
            return RLIST.error().message("图片不符合");
        }
        FaceFeature faceFeature = instance.getExtractFaceFeature(imageInfo2, detectFaces);
        List<PhotoGallery> inquire = photoGalleryService.inquire(docId);
        if(inquire != null || inquire.size() != 0){
            for (PhotoGallery photogallery1 : inquire) {
                String eigenvalue = photogallery1.getEigenvalue();
                byte[] byteArray = Base64.getDecoder().decode(eigenvalue);
                FaceSimilar faceSimilar = instance.compareFace(faceFeature.getFeatureData(),byteArray);
                if(faceSimilar.getScore()>scoreMax){
                    float score = faceSimilar.getScore()*100;
                    faceVo.setScore(score);
                    faceVo.setName(photogallery1.getName());
                    faceVo.setLeft(faceInfo.getRect().getLeft());
                    faceVo.setTop(faceInfo.getRect().getTop());
                    faceVo.setRight(faceInfo.getRect().getRight());
                    faceVo.setBottom(faceInfo.getRect().getBottom());
                    faceVo.setOrient(faceInfo.getOrient());
                    scoreMax = faceSimilar.getScore();
                }

            }
            return RLIST.ok().data("data",faceVo);
        }

        return RLIST.ok();


    }

    //    车牌识别

    @ApiOperation(value = "车牌识别")
    @PostMapping("plateDetection")
    public RLIST plateDetection (@RequestParam("file") MultipartFile multipartFile, PlateDeteVo plateDeteVo){

        String originalFilename = multipartFile.getOriginalFilename();

        String format = originalFilename.substring(originalFilename.length() - 4);
        if(!(format.equalsIgnoreCase(".jpg") || format.equalsIgnoreCase("jpeg"))){
            return RLIST.error().message("格式异常 需要jpg或jpeg");
        }
        String filePath = "D:\\plateDetection\\";
        File file = new File(filePath+originalFilename);
        if(!file.getParentFile().exists()){   //这里就判断了文件夹是否存在
            file.getParentFile().mkdirs();	//如果不存在就创建文件夹
        }
        try {
            multipartFile.transferTo(file);
        } catch (IOException e) {
            e.printStackTrace();
        }

        CacheSingleton instance = CacheSingleton.getInstance();
        String token = instance.getValue("token");
        if(token == null || token.equals("")){
            TokenResponse budaiToken = ResponseUtil.getBudaiToken();
            token = budaiToken.getAccess_token();
            instance.setValue("token",token,budaiToken.getExpires_in());

        }
        String budaiData = ResponseUtil.getBudaiData(originalFilename, token, plateDeteVo.getMultiDetect(), plateDeteVo.getMultiScal());
        JSONObject jsonObject = JSONObject.parseObject(budaiData);
        JsonRootBean jsonRootBean = JSON.toJavaObject(jsonObject, JsonRootBean.class);

        boolean b = plateNumberService.addPlateNumber(jsonRootBean);


        return RLIST.ok().data("data",jsonRootBean).data("fla",b);

    }


}


